// 2025/8/26
// kotori和素因子
// deepseek完成

#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>
#include <climits>
using namespace std;

const int INF = INT_MAX;

// 获取一个数的所有素因子（去重）
vector<int> getPrimeFactors(int x) {
    vector<int> factors;
    int temp = x;
    for (int i = 2; i * i <= temp; i++) {
        if (temp % i == 0) {
            factors.push_back(i);
            while (temp % i == 0) {
                temp /= i;
            }
        }
    }
    if (temp > 1) {
        factors.push_back(temp);
    }
    return factors;
}

// 最小费用流类
struct MinCostFlow {
    struct Edge {
        int to, cap, cost, rev;
    };
    int n;
    vector<vector<Edge>> graph;
    vector<int> dist, prevv, preve;
    vector<bool> inque;

    MinCostFlow(int n) : n(n), graph(n), dist(n), prevv(n), preve(n), inque(n) {}

    void addEdge(int from, int to, int cap, int cost) {
        graph[from].push_back({to, cap, cost, (int)graph[to].size()});
        graph[to].push_back({from, 0, -cost, (int)graph[from].size()-1});
    }

    int run(int s, int t, int f) {
        int res = 0;
        while (f > 0) {
            fill(dist.begin(), dist.end(), INF);
            fill(inque.begin(), inque.end(), false);
            dist[s] = 0;
            queue<int> que;
            que.push(s);
            inque[s] = true;
            while (!que.empty()) {
                int u = que.front(); que.pop();
                inque[u] = false;
                for (int i = 0; i < graph[u].size(); i++) {
                    Edge& e = graph[u][i];
                    if (e.cap > 0 && dist[e.to] > dist[u] + e.cost) {
                        dist[e.to] = dist[u] + e.cost;
                        prevv[e.to] = u;
                        preve[e.to] = i;
                        if (!inque[e.to]) {
                            que.push(e.to);
                            inque[e.to] = true;
                        }
                    }
                }
            }
            if (dist[t] == INF) {
                return -1;
            }
            int d = f;
            for (int v = t; v != s; v = prevv[v]) {
                d = min(d, graph[prevv[v]][preve[v]].cap);
            }
            f -= d;
            res += d * dist[t];
            for (int v = t; v != s; v = prevv[v]) {
                Edge& e = graph[prevv[v]][preve[v]];
                e.cap -= d;
                graph[e.to][e.rev].cap += d;
            }
        }
        return res;
    }
};

int main() {
    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }

    // 获取每个数字的素因子列表
    vector<vector<int>> factorsList(n);
    map<int, int> primeToIndex;
    vector<int> primes;

    for (int i = 0; i < n; i++) {
        factorsList[i] = getPrimeFactors(a[i]);
        for (int p : factorsList[i]) {
            if (primeToIndex.find(p) == primeToIndex.end()) {
                primeToIndex[p] = primes.size();
                primes.push_back(p);
            }
        }
    }

    int m = primes.size();
    int nodeS = 0;
    int nodeT = n + m + 1;
    int totalNodes = nodeT + 1;
    MinCostFlow mcf(totalNodes);

    // 源点连接到数字节点
    for (int i = 0; i < n; i++) {
        mcf.addEdge(nodeS, i + 1, 1, 0);
    }

    // 数字节点连接到素因子节点
    for (int i = 0; i < n; i++) {
        for (int p : factorsList[i]) {
            int j = primeToIndex[p];
            mcf.addEdge(i + 1, n + 1 + j, 1, p);
        }
    }

    // 素因子节点连接到汇点
    for (int j = 0; j < m; j++) {
        mcf.addEdge(n + 1 + j, nodeT, 1, 0);
    }

    int cost = mcf.run(nodeS, nodeT, n);
    if (cost == -1) {
        cout << -1 << endl;
    } else {
        cout << cost << endl;
    }

    return 0;
}